#ifndef AC_COMMON_STACK_PTR_HPP_
#define AC_COMMON_STACK_PTR_HPP_

#include <cassert>

template <typename T>
class StackPtr
{
public:
    explicit StackPtr(T* p = 0)
        : ptr(p)
    {
    }

    StackPtr(StackPtr& other)
        : ptr(other.release())
    {
    }

    ~StackPtr()
    {
        del();
    }

    StackPtr& operator = (StackPtr& other)
    {
        reset(other.release());
        return *this;
    }

    T& operator* () const {return *ptr;}
    T* operator-> () const {return ptr;}
    T* get() const {return ptr;}
    operator T* () const {return ptr;}

    T* release() {T* p = ptr; ptr = 0; return p;}

    void del() {delete ptr; ptr = 0;}
    void reset(T* p)
    {
        assert(ptr == 0);
        ptr = p;
    }

    StackPtr& operator = (T* p)
    {
        reset(p);
        return *this;
    }

private:

    StackPtr(const StackPtr& other);
    StackPtr& operator = (const StackPtr& other);

    T*  ptr;
};

#endif  // AC_COMMON_STACK_PTR_HPP_
